dojo.provide("slipstream.form.FilteringSelect");

dojo.require("dijit.form.FilteringSelect");

	
dojo.declare("slipstream.form.FilteringSelect", [dijit.form.FilteringSelect], {
	keyAttr: '$rel',
	compare: function(/*anything*/val1, /*anything*/val2){
		// summary:
		//		Compare 2 values (as returned by attr('value') for this widget).
		// tags:
		//		protected
		if(val1 !== val2){
			return 1;
		}else{
			return 0;
		}
	},
	_setValueAttr: function(/*String*/value, /*Boolean?*/ priorityChange){
		//console.log(value, 'Input');
		// summary:
		//		Hook so attr('value', value) works.
		// description:
		//		Sets the value of the select.
		//		Also sets the label to the corresponding value by reverse lookup.
		if (!this._onChangeActive) {
			priorityChange = null;
		}
		this._lastQuery = value;
		
		if (value === null) {
			this._setDisplayedValueAttr('', priorityChange);
			return;
		}
		
		//#3347: fetchItemByIdentity if no keyAttr specified
		var self = this;
		var handleFetchByIdentity = function(item, priorityChange){
			if (item) {
				if (self.store.isItemLoaded(item)) {
					self._callbackSetLabel([item], undefined, priorityChange);
				}
				else {
					self.store.loadItem({
						item: item,
						onItem: function(result, dataObject){
							self._callbackSetLabel(result, dataObject, priorityChange);
						}
					});
				}
			}
			else {
				self._isvalid = false;
				// prevent errors from Tooltip not being created yet
				self.validate(false);
			}
		}
		if (dojo.isObject(value) && !value.length) {
			//console.log(value, 'Is object');
			/*if(this.store.isItemLoaded(value)) this.store.loadItem(value);
			this._callbackSetLabel(value, undefined, priorityChange);*/
			if (!this.store.isItemLoaded(value)) {
				//console.log(value, 'Staring load on ');
				this,dojox.data.ServiceStore.prototype.loadItem({item:value});
				//console.log(value, 'loaded');
			};
				/* else{
					this,dojox.data.ServiceStore.prototype.loadItem({item:value})
				this.store.loadItem({
					item: value,
					onItem: function(result, dataObject){
						self._callbackSetLabel(result, dataObject, priorityChange);
					}
				});
			};*/
			this._callbackSetLabel(value, undefined, priorityChange);
		}
		else {
			//console.log(value, 'Is string');
			this.store.fetchItemByIdentity({
				identity: value,
				onItem: function(item){
					handleFetchByIdentity(item, priorityChange);
				}
			});
		}
	},
	
	_callbackSetLabel: function( /*Array*/result, /*Object*/
	dataObject, /*Boolean?*/
	priorityChange){
		
		//console.log(result, '_callbackSetLabel');
		//if(dojo.isArray(result) && dojo.isObject(result[0])) result=result[0];
		// summary:
		//		Callback function that dynamically sets the label of the
		//		ComboBox
		
		// setValue does a synchronous lookup,
		// so it calls _callbackSetLabel directly,
		// and so does not pass dataObject
		// still need to test against _lastQuery in case it came too late
		//if (!dojo.isObject(result)) {
			//if ((dataObject && dataObject.query[this.searchAttr] != this._lastQuery) || (!dataObject && (result.length || dojo.isObject(result)) && this.store.getIdentity(result) != this._lastQuery)) {
			if((dataObject && dataObject.query[this.searchAttr] != this._lastQuery)||(!dataObject && result.length && this.store.getIdentity(result[0])!= this._lastQuery)){
				//console.log(dataObject,this._lastQuery,'some wierd error');
				return;
			}
		//}
		//console.log(result, 'Label callback');
		if (!result.length && !dojo.isObject(result)) {
			//#3268: do nothing on bad input
			//this._setValue("", "");
			//#3285: change CSS to indicate error
			if (priorityChange || !this._focused) {
				this.valueNode.value = "";
			}
			//console.log('Parent _setValueAttr');
			dijit.form.TextBox.superclass._setValueAttr.call(this, "", priorityChange || !this._focused);
			this._isvalid = false;
			this.validate(this._focused);
			this.item = null;
		}
		else {
			if(dojo.isArrayLike(result)){
				//console.log(result, 'Send array selected obj');
				this._setValueFromItem(result[0], priorityChange);
			} else {
				//console.log(result, 'Send straight obj');
				this._setValueFromItem(result, priorityChange);
			}
		}
	},
	
	_setValueFromItem: function(/*item*/item, /*Boolean?*/ priorityChange){
		//	summary:
		//		Set the displayed valued in the input box, based on a
		//		selected item.
		//	description:
		//		Users shouldn't call this function; they should be calling
		//		attr('displayedValue', value) instead
		this._isvalid = true;
		this.item = item; // Fix #6381
		//console.log(item, 'Sending value to set');
		if (this.keyAttr.length) {
			if(dojo.isArrayLike(item) && dojo.isObject(item[0])){
				//console.log(this.keyAttr, 'Has custom key');
				this._setValue(item[0], this.labelFunc(item[0], this.store), priorityChange);
			} else if(dojo.isObject(item)){
				this._setValue(item, this.labelFunc(item, this.store), priorityChange);
				
			}
		}
		else {
			this._setValue(this.store.getIdentity(item), this.labelFunc(item, this.store), priorityChange);
		}
	},
	
	labelFunc: function(/*item*/item, /*dojo.data.store*/ store){
		// summary: Event handler called when the label changes
		// return: the label that the ComboBox should display
		//console.log(item,store, 'Getting label data');
		return store.getValue(item, this.searchAttr);
	},
	
	_setValue: function( /*String*/value, /*String*/
	displayedValue, /*Boolean?*/
	priorityChange){
			//console.log(value, 'Setting value');
		if (dojo.isObject(value) && !value.length) {
			this.valueNode.value = value[this.keyAttr];
			this.valueObj = value;
		}
		else {
			this.valueNode.value = value;
		}
		console.log(this._onChangeActive,'Fire onchange start');
		dijit.form.FilteringSelect.superclass._setValueAttr.call(this, value, priorityChange, displayedValue);
		console.log(this._onChangeActive,'Fire onchange done');
		this._lastDisplayedValue = displayedValue;
	},
	
	_getValueAttr: function(){
		// summary:
		//		Hook for attr('value') to work.
		
		// don't get the textbox value but rather the previously set hidden value
		// TODO: seems suspicious that we need this; how is FilteringSelect different
		// than another MappedTextBox widget?
		console.log('Value:',this.valueObj);
		if (dojo.isObject(this.valueObj)) return this.valueObj;
		return this.valueNode.value;
	},

	_setDisplayedValueAttr: function(/*String*/ label, /*Boolean?*/ priorityChange){
		// summary:
		//		Hook so attr('displayedValue', label) works.
		// description:
		//		Set textbox to display label. Also performs reverse lookup
		//		to set the hidden value.

		// When this is called during initialization it'll ping the datastore
		// for reverse lookup, and when that completes (after an XHR request)
		// will call setValueAttr()... but that shouldn't trigger an onChange()
		//  event, even when it happens after creation has finished
		if(!this._created){
			priorityChange = false;
		}

		if(this.store){
			var query = dojo.clone(this.query); // #6196: populate query with user-specifics
			// escape meta characters of dojo.data.util.filter.patternToRegExp().
			this._lastQuery = query[this.searchAttr] = label.replace(/([\\\*\?])/g, "\\$1");
			// if the label is not valid, the callback will never set it,
			// so the last valid value will get the warning textbox set the
			// textbox value now so that the impending warning will make
			// sense to the user
			this.textbox.value = label;
			this._lastDisplayedValue = label;
			var _this = this;
			var fetch = {
				query: query, 
				queryOptions: {
					ignoreCase: this.ignoreCase, 
					deep: true
				}, 
				onComplete: function(result, dataObject){
							//console.log(result,'Fetch lable results');
					        dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange);
				},
				onError: function(errText){
					console.error('dijit.form.FilteringSelect: ' + errText);
					dojo.hitch(_this, "_setValue")("", label, false);
				}
			};
			dojo.mixin(fetch, this.fetchProperties);
			this.store.fetch(fetch);
		}
	}
});